/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.common.mybatis.ext.sql.support.select;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import java.util.regex.Pattern;
import lombok.Getter;
import org.elsfs.cloud.common.util.lang.NamingCase;
import org.elsfs.cloud.common.util.lang.StringUtils;

/** 表达式选择项实现 */
@Getter
public class ExpressionSelectItem implements SelectItem {

  /** 字段别名分割正则模式 */
  private static final Pattern FIELD_ALIAS_SPLITTING_PATTERN =
      Pattern.compile("( +as +(?=\\w+$))|( +(?=\\w+$))", Pattern.CASE_INSENSITIVE);

  /** 字段表达式 */
  private final String expression;

  /** 字段名别 */
  private final String fieldAlias;

  /**
   * 构造函数
   *
   * @param expression 字段表达式
   */
  public ExpressionSelectItem(String expression) {
    if (StringUtils.isBlank(expression)) {
      throw new MybatisPlusException("选择字段表达式不能为空");
    }

    String[] tokens = FIELD_ALIAS_SPLITTING_PATTERN.split(expression);
    if (tokens.length == 0) {
      throw new MybatisPlusException("选择字段表达式不能为空");
    }

    if (tokens.length == 1) {
      this.expression = tokens[0];
      this.fieldAlias = null;
      return;
    }

    this.expression = tokens[0];
    this.fieldAlias = tokens[1];
  }

  /**
   * 构建SQL片段
   *
   * @return SQL片段
   */
  @Override
  public String buildSqlFragment() {
    StringBuilder stringBuilder = new StringBuilder();
    if (StringUtils.isBlank(this.fieldAlias)) {
      stringBuilder.append(NamingCase.toUnderlineCase(this.expression));
    } else {
      stringBuilder
          .append(NamingCase.toUnderlineCase(this.expression))
          .append(" AS ")
          .append(NamingCase.toUnderlineCase(this.fieldAlias));
    }

    return stringBuilder.toString();
  }
}
